package pe.com.trestperu.common.controller;

import java.util.Collections;
import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import pe.com.trestperu.common.listener.ContextLoaderListener;

@SuppressWarnings("unchecked")
@Controller("genericController")
public class GenericController {

	protected final String FLAG_BEAN_LIST = "FLAG_BEAN_LIST";
	
	private Object beanClassName;
	
	protected Log log;
	
	protected String message = "";

	protected String messageError = "";
	
	protected final String FLAG_LOAD = "FLAG_LOAD";

	protected final String FLAG_VIEW = "FLAG_VIEW";

	public GenericController() {
		log = LogFactory.getLog(this.getClass());
	}

	/**
	 * Method to get Spring instance from Controller
	 * 
	 * @param name
	 * @return Object
	 */
	public Object getSpringBean(String name) {
		return ContextLoaderListener.getBean(name);
	}

	/**
	 * Method to get Spring instance from Controller
	 * 
	 * @param nameObj
	 * @return Object
	 */
    public Object getSpringBean(Class nameObj){
    	return getSpringBean(ClassUtils.getShortName(nameObj));
    }

    /**
     * Method to get Spring instance from Controller
     * 
     * @param nameObj
     * @return Object
     */
    public Object getSpringBean(Object nameObj){
    	return getSpringBean(nameObj.getClass());
    }

	/**
	 * Method to init form, clear every variable in ModelAndView instance
	 * and fill bean with Object spring instance
	 * 
	 * @param request
	 * @param response
	 * @return ModelAndView
	 * @throws Exception
	 */
    @RequestMapping("/{bean}/init")
	public ModelAndView init(@PathVariable("bean") String bean, HttpServletRequest request, ModelAndView modelAndView) throws Exception{

        ModelAndView v = new ModelAndView();

		if(!StringUtils.isEmpty(bean))
	        v.addObject("bean", getSpringBean(bean));

		v.addObject("beanList", Collections.EMPTY_LIST);
		v.addObject("map", new HashMap());
		v.addObject("id", null);
		v.addObject("selectId", null);

		boolean _return = initializeForm(request, v);

		if(_return){
	        return displayController(request, v);
		}else{
			return null;
		}
	}

	/**
	 * Method to redirect to any page configured in springMVC
	 * reading forward request parameter and for default this
	 * send to init
	 * 
	 * @param request
	 * @param response
	 * @return ModelAndView
	 * @throws Exception
	 */
    @RequestMapping("/displayController")
	public ModelAndView displayController(HttpServletRequest request, ModelAndView modelAndView) throws Exception {
		String forward = request.getParameter("forward");
		if (StringUtils.isEmpty(forward))
			forward = "init";

		modelAndView.setViewName(forward);
		return modelAndView;
	}

	/**
	 * Method to initialize ModelAndView variables after init return true when
	 * init method will return ModelAndView and false when init method
	 * will return null
	 * 
	 * @param request
	 * @param response
	 * @param modelAndView
	 * @return boolean
	 * @throws Exception
	 */
	protected boolean initializeForm(HttpServletRequest request, ModelAndView modelAndView)  throws Exception{
		return true;
	}

	/**
	 * Return Spring instances configured in applicationContext
	 * 
	 * @return Object
	 */
    public Object getBeanClassName() {
		return beanClassName;
	}

    /**
     * Method to set Spring instance
     * 
     * @param beanClassName
     */
	public void setBeanClassName(Object beanClassName) {
		this.beanClassName = beanClassName;
	}
}